﻿using FireChat.Server.Database.Table.Accounts;
using FireChat.Server.Session.Receiver;
using FireChat.Share.Database.Util;
using FireChat.Share.Web.Model.Response;
using FireChat.Share.Web.Model.Enums;
using FireChat.Share.Web.Package;
using FireChat.Share.Web.Model.Query.Contacts;

namespace FireChat.Server.Database.Manager;


/// <summary>
/// 事件管理
/// </summary>
internal static class ContactsManager
{
    /// <summary>
    /// 获取目标Id
    /// </summary>
    public static (int? Id, AccountType Type) GetTargetId(object target, AccountType accountType)
    {
        int? target_id = null;

        if (accountType == AccountType.Account)
        {
            target_id = AccountManager.GetInstanceByName((string)target)?.Id;
        }
        else if (accountType == AccountType.Group)
        {
            target_id = (int)target;
        }

        return (target_id, accountType);
    }

    /// <summary>
    /// 判断两个账户是否是联系人
    /// </summary>
    public static bool IsContacts(int accountId, int targetId, AccountType accountType)
    {
        return GetInstance(accountId, targetId, accountType) != null;
    }

    /// <summary>
    /// 获取联系人数据实例
    /// </summary>
    public static ContactData? GetInstance(int accountId, int targetId, AccountType accountType)
    {
        return DataTableManager<ContactData>.Select(x =>
        {
            if (x.TargetType != accountType) return false;

            if (x.TargetId == targetId && x.AccountId == accountId) return true;
            if (x.TargetId == accountId && x.AccountId == targetId) return true;

            return false;

        }).FirstOrDefault();
    }

    /// <summary>
    /// 获取联系人申请数据实例
    /// </summary>
    public static ContactApplyData? GetApplyInstance(int accountId, int targetId, AccountType accountType)
    {
        return DataTableManager<ContactApplyData>.Select(x =>
        {
            if (x.TargetType != accountType) return false;

            return x.TargetId == targetId && x.AccountId == accountId;

        }).FirstOrDefault();
    }




    /// <summary>
    /// 申请联系人
    /// </summary>
    /// <param name="targetId">目标Id</param>
    /// <param name="accountType">目标类型</param>
    public static ServerPackage ApplyContact(this PackageReceiver receiver, int targetId, AccountType accountType)
    {
        /////////////// 前置判断 ///////////////
        var account_id = receiver.Session.GetAccountID();

        if (IsContacts(targetId, account_id, accountType))
        {
            return receiver.ReplyFailureAsync("该目标已经是你的联系人");
        }

        if (GetApplyInstance(targetId, account_id, accountType) is not null)
        {
            return receiver.ReplyFailureAsync("已经向该目标发送申请 无需重复申请");
        }

        /////////////// 添加申请 ///////////////
        ContactApplyData data = new()
        {
            AccountId = account_id,
            TargetId = targetId,
            TargetType = AccountType.Account,
            IsProcessed = false
        };

        var count = DataTableManager<ContactApplyData>.Insert(data);
        return receiver.ReplyExpressAsync(count > 0, "申请成功", "申请失败!");
    }

    /// <summary>
    /// 删除联系人
    /// </summary>
    public static ServerPackage DeleteContact(this PackageReceiver receiver, int targetId, AccountType accountType)
    {
        var account_id = receiver.Session.GetAccountID();

        if (GetInstance(account_id, targetId, accountType) is not ContactData contact)
        {
            return receiver.ReplyFailureAsync("该目标不是你的联系人");
        }

        var count = DataTableManager<ContactData>.Delete(contact.Id);
        return receiver.ReplyExpressAsync(count > 0, "删除成功", "删除失败");
    }

    /// <summary>
    /// 同意联系人申请
    /// </summary>
    /// <returns></returns>
    public static ServerPackage AgreeContactApply(this PackageReceiver receiver, int targetId, AccountType accountType)
    {
        /////////////// 前置判断 ///////////////
        var account_id = receiver.Session.GetAccountID();

        if (IsContacts(account_id, targetId, accountType))
        {
            return receiver.ReplyFailureAsync("该目标已经是你的联系人");
        }

        if (GetApplyInstance(targetId, account_id, accountType) is not ContactApplyData contact_apply)
        {
            return receiver.ReplyFailureAsync("未收到该目标的申请");
        }

        /////////////// 完成请求 ///////////////
        var update_count = DataTableManager<ContactApplyData>.Update(contact_apply.Id, x =>
        {
            x.IsProcessed = true;
            return x;
        });

        /////////////// 添加联系人 ///////////////
        var data = new ContactData()
        {
            AccountId = account_id,
            TargetId = targetId,
            TargetType = accountType
        };

        var insert_count = DataTableManager<ContactData>.Insert(data);
        return receiver.ReplyExpressAsync(update_count != 0 && insert_count != 0, "操作成功", "操作失败");
    }

    /// <summary>
    /// 获取好友申请列表
    /// </summary>
    /// <returns></returns>
    public static ServerPackage GetFriendApplys(this PackageReceiver receiver)
    {
        var account_id = receiver.Session.GetAccountID();

        var result = DataTableManager<ContactApplyData>.Select(x => x.AccountId == account_id &&
            x.TargetType == AccountType.Account && !x.IsProcessed);



        var datas = from i in result
                    let name = AccountManager.GetInstance(x => x.Id == i.Id)?.Username
                    where name is not null
                    select new FriendApply() { Username = name, AppltTime = i.CreatedTime };

        return receiver.ReplySuccessAsync("OK", datas);
    }
}